/*
 * Copyright (C) 2010, Funcom AS, All Rights Reserved
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *  @authors
 *  Svein Gunnar Larsen <sveingunnarlarsen@gmail.com>
 *  Erik Thune Lund <culex.eriklund@gmail.com>
 *  Michel Krohn-Dale <kronicz@gmail.com>
 */

package com.funcom.peeler.properties;

import com.funcom.peeler.PeelStyleSheet;
import com.funcom.peeler.WorkBench;
import com.funcom.peeler.adapter.KeyAndMouseAdapter;
import com.funcom.peeler.peelable.PeelComponent;
import com.funcom.peeler.symbol.Symbol;
import com.funcom.peeler.utils.ColorPicker;
import com.funcom.peeler.utils.FileChooser;
import com.funcom.peeler.utils.NumberErrorMessage;
import com.jme.renderer.ColorRGBA;
import com.jmex.bui.enumeratedConstants.ImageBackgroundMode;
import com.jmex.bui.property.BackgroundProperty;
import com.jmex.bui.property.IconProperty;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Set;

// Class for the background tab in the component properties window.
public class BackgroundSetting extends UpdateableProperties {

    JButton remove;
    JButton load;
    JButton alphaButton;
    JTextField alphaText;
    JComboBox scale;
    JCheckBox icon;
    ColorRGBA colorRGBA;
    JPanel pnlColor;
    Color defaultColor = new Color(204, 204, 204);
    String pathToFile;

    public BackgroundSetting(JButton remove,
                             JButton loadBackground,
                             JComboBox scale,
                             JCheckBox icon,
                             JPanel pnlColor,
                             JTextField alphaText,
                             JButton alphaButton) {
        this.remove = remove;
        this.load = loadBackground;
        this.scale = scale;
        this.icon = icon;
        this.pnlColor = pnlColor;
        this.alphaText = alphaText;
        this.alphaButton = alphaButton;

        this.pnlColor.setBackground(defaultColor);
        this.pnlColor.setBorder(BorderFactory.createEtchedBorder());

        initListeners();
    }

    public void update() {

        fields_cleared = false;

        String styleclass = selectedComp.getComponent().getStyleClass();

        if (selectedComp.getComponent().getWindow() == null) return;

        float alpha = selectedComp.getComponent().getAlpha();

        int value = (int)(alpha * 100);

        alphaText.setText("" + value);

        PeelStyleSheet stylesheet = selectedComp.getStyleSheet();
        BackgroundProperty background;

        if (stylesheet.properties.get( styleclass ) == null) return;

        if (stylesheet.properties.get( styleclass ).properties.get( Symbol.StyleProperty.background ) == null) {
            background = null;
        } else {
            background = (BackgroundProperty)stylesheet.properties.get( styleclass ).properties.get( Symbol.StyleProperty.background );
        }

        if ( background == null ){
            pnlColor.setBackground( new Color( 204, 204, 204 ) );
            return;
        }
        ColorRGBA bgColor = background.color;
        if ( bgColor == null ) {
            pnlColor.setBackground( new Color( 204, 204, 204 ) );
            return;
        }

        Color current_color = new Color( bgColor.r, bgColor.g, bgColor.b, bgColor.a );
        if ( !pnlColor.getBackground().equals( current_color ) ) {
            pnlColor.setBackground( current_color );
        }
    }

    public void needUpdate( WorkBench workBench,
                            Set<PeelComponent> allComp,
                            Set<PeelComponent> selectedComps,
                            PeelComponent main_selected,
                            PropertiesFrame thisFrame ) {

        if  (main_selected == null) {
            selectedComp = null;
            if (!fields_cleared) {
                clear();
                return;
            } else {
                return;
            }
        }
        if (selectedComp != main_selected) {
            wantUpdate = true;
            selectedComp = main_selected;
        }
    }

    public void clear() {

        pnlColor.setBackground( new Color( 204, 204, 204 ) );
        alphaText.setText("");

        fields_cleared = true;
    }

    public void applyChange( PeelComponent component, PropertiesFrame updater) {

        switch(change) {
            case BACKGROUND_CLEAR: {

                BackgroundProperty newProp = new BackgroundProperty();
                newProp.type = "blank";

                updater.applyToSelectedStates(component, newProp);

                break;
            }
            case BACKGROUND_COLOR: {

                BackgroundProperty newProp = new BackgroundProperty();
                newProp.type = "solid";
                newProp.color = colorRGBA;

                updater.applyToSelectedStates(component, newProp);

                break;
            }
            case BACKGROUND_IMAGE: {

                if (icon.isSelected()) {

                    // TODO: This is not working properly, setting a new icon to a label generates a WARNING: Unreferenced image released name!

                    IconProperty newProp = new IconProperty();
                    newProp.ipath = pathToFile;
                    newProp.type = "image";

                    updater.applyToSelectedStates(component, newProp);

                } else {

                BackgroundProperty newProp = new BackgroundProperty();

                ImageBackgroundMode mode = ImageBackgroundMode.fromInt(scale.getSelectedIndex());

                newProp.ipath = pathToFile;
                newProp.scaleMode = mode;
                newProp.type = "image";

                updater.applyToSelectedStates(component, newProp);

                }
                break;
            }
            case ALPHA: {

                try {

                    int alpha = Integer.parseInt(alphaText.getText());

                    if (alpha < 0 || alpha > 200) {
                        SwingUtilities.invokeLater( new Runnable() {
                            public void run() {
                                NumberErrorMessage.numberError("Not a valid number");
                            }
                        });
                        alphaText.setText("");
                        return;
                    }

                    float value = (alpha / 100f);
                    component.getComponent().setAlpha(value);

                } catch (NumberFormatException e) {
                    SwingUtilities.invokeLater( new Runnable() {
                        public void run() {
                            NumberErrorMessage.numberError("Not a valid number");
                        }
                    });
                    alphaText.setText("");
                }
                break;
            }
        }
    }

    protected void initListeners() {

        remove.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                change = ChangeProp.BACKGROUND_CLEAR;
            }
        });

        load.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                pathToFile = FileChooser.selectFile();
                if ( pathToFile == null ) return;
                change = ChangeProp.BACKGROUND_IMAGE;
            }
        });

        alphaText.addKeyListener(new KeyAndMouseAdapter(){
            public void keyPressed(KeyEvent e){
                if(e.getKeyCode() == KeyEvent.VK_ENTER) {
                    change = ChangeProp.ALPHA;
                }
            }
        });
        
        alphaButton.addActionListener( new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                change = ChangeProp.ALPHA;
            }
        });

        pnlColor.addMouseListener(new KeyAndMouseAdapter() {
            public void mouseClicked(MouseEvent evt) {

                colorRGBA = ColorPicker.selectColor(pnlColor, "Set background color");

                if (colorRGBA != null) {
                    change = ChangeProp.BACKGROUND_COLOR;
                }
            }
        });
    }
}
